{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "3d75b4c1",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "from tensorflow.keras.models import Sequential\n",
    "from tensorflow.keras.layers import Dense, Flatten\n",
    "from tensorflow.keras.optimizers import Adam\n",
    "import pyarrow.parquet as pq\n",
    "from sklearn.model_selection import train_test_split\n",
    "import csv\n",
    "import subprocess\n",
    "import getpass\n",
    "import os\n",
    "import gzip\n",
    "from os import listdir\n",
    "from os.path import isfile, join\n",
    "from SciServer import Authentication\n",
    "import tensorflow as tf\n",
    "from tensorflow.keras.callbacks import ReduceLROnPlateau, EarlyStopping\n",
    "from tensorflow.keras.optimizers import Adam\n",
    "from tensorflow.keras.metrics import AUC"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eecf0b25-5d8c-4d79-a361-d229fc0106ed",
   "metadata": {},
   "source": [
    "# Data Loading"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "9368f448",
   "metadata": {},
   "outputs": [],
   "source": [
    "df_dataset = pd.read_csv(\"/home/idies/workspace/SAFE/MinooEmir/new_complete_features.csv\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "4c31bdb5-8787-46c1-8738-11cd28dded51",
   "metadata": {},
   "outputs": [],
   "source": [
    "df_dataset = df_dataset[['formatted_time', 'hf_original', 'hf_type_original', 'HDL',\n",
    "       'tot_cholesterol', 'glucose', 'bnp',\n",
    "       'Arterial Blood Pressure diastolic', 'Arterial Blood Pressure systolic',\n",
    "       'Heart Rate', 'gender', 'race', 'age']]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "37191c06",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Index(['formatted_time', 'hf_original', 'hf_type_original', 'HDL',\n",
       "       'tot_cholesterol', 'glucose', 'bnp',\n",
       "       'Arterial Blood Pressure diastolic', 'Arterial Blood Pressure systolic',\n",
       "       'Heart Rate', 'gender', 'race', 'age'],\n",
       "      dtype='object')"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_dataset.columns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "31bab527-db57-49ee-af64-64877f72eb9c",
   "metadata": {},
   "outputs": [],
   "source": [
    "feature_list = ['HDL',\n",
    "               'tot_cholesterol', \n",
    "               'glucose', \n",
    "               'bnp',\n",
    "               'Arterial Blood Pressure diastolic', \n",
    "               'Arterial Blood Pressure systolic',\n",
    "               'Heart Rate', \n",
    "               'gender', \n",
    "               'race', \n",
    "               'age']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "a85aa509",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>hf_original</th>\n",
       "      <th>hf_type_original</th>\n",
       "      <th>HDL</th>\n",
       "      <th>tot_cholesterol</th>\n",
       "      <th>glucose</th>\n",
       "      <th>bnp</th>\n",
       "      <th>Arterial Blood Pressure diastolic</th>\n",
       "      <th>Arterial Blood Pressure systolic</th>\n",
       "      <th>Heart Rate</th>\n",
       "      <th>gender</th>\n",
       "      <th>race</th>\n",
       "      <th>age</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>formatted_time</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>13:45:00_11_01_2110_18106347</th>\n",
       "      <td>0</td>\n",
       "      <td>Non-HF</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>95.000000</td>\n",
       "      <td>NaN</td>\n",
       "      <td>66.068966</td>\n",
       "      <td>108.655172</td>\n",
       "      <td>100.800000</td>\n",
       "      <td>0</td>\n",
       "      <td>6</td>\n",
       "      <td>48</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>04:02:00_17_01_2110_18780420</th>\n",
       "      <td>0</td>\n",
       "      <td>Non-HF</td>\n",
       "      <td>56.0</td>\n",
       "      <td>159.0</td>\n",
       "      <td>113.000000</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>59.958333</td>\n",
       "      <td>1</td>\n",
       "      <td>7</td>\n",
       "      <td>84</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>02:02:00_22_01_2110_16006168</th>\n",
       "      <td>0</td>\n",
       "      <td>Non-HF</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>96.142857</td>\n",
       "      <td>NaN</td>\n",
       "      <td>80.428571</td>\n",
       "      <td>131.785714</td>\n",
       "      <td>92.785714</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>20</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17:21:00_30_01_2110_14816979</th>\n",
       "      <td>0</td>\n",
       "      <td>Non-HF</td>\n",
       "      <td>39.0</td>\n",
       "      <td>189.0</td>\n",
       "      <td>98.133333</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>96.173913</td>\n",
       "      <td>1</td>\n",
       "      <td>7</td>\n",
       "      <td>30</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17:07:00_01_02_2110_13956717</th>\n",
       "      <td>0</td>\n",
       "      <td>Non-HF</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>106.777778</td>\n",
       "      <td>NaN</td>\n",
       "      <td>52.473684</td>\n",
       "      <td>98.684211</td>\n",
       "      <td>80.157895</td>\n",
       "      <td>1</td>\n",
       "      <td>7</td>\n",
       "      <td>72</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                              hf_original hf_type_original   HDL  \\\n",
       "formatted_time                                                     \n",
       "13:45:00_11_01_2110_18106347            0           Non-HF   NaN   \n",
       "04:02:00_17_01_2110_18780420            0           Non-HF  56.0   \n",
       "02:02:00_22_01_2110_16006168            0           Non-HF   NaN   \n",
       "17:21:00_30_01_2110_14816979            0           Non-HF  39.0   \n",
       "17:07:00_01_02_2110_13956717            0           Non-HF   NaN   \n",
       "\n",
       "                              tot_cholesterol     glucose  bnp  \\\n",
       "formatted_time                                                   \n",
       "13:45:00_11_01_2110_18106347              NaN   95.000000  NaN   \n",
       "04:02:00_17_01_2110_18780420            159.0  113.000000  NaN   \n",
       "02:02:00_22_01_2110_16006168              NaN   96.142857  NaN   \n",
       "17:21:00_30_01_2110_14816979            189.0   98.133333  NaN   \n",
       "17:07:00_01_02_2110_13956717              NaN  106.777778  NaN   \n",
       "\n",
       "                              Arterial Blood Pressure diastolic  \\\n",
       "formatted_time                                                    \n",
       "13:45:00_11_01_2110_18106347                          66.068966   \n",
       "04:02:00_17_01_2110_18780420                                NaN   \n",
       "02:02:00_22_01_2110_16006168                          80.428571   \n",
       "17:21:00_30_01_2110_14816979                                NaN   \n",
       "17:07:00_01_02_2110_13956717                          52.473684   \n",
       "\n",
       "                              Arterial Blood Pressure systolic  Heart Rate  \\\n",
       "formatted_time                                                               \n",
       "13:45:00_11_01_2110_18106347                        108.655172  100.800000   \n",
       "04:02:00_17_01_2110_18780420                               NaN   59.958333   \n",
       "02:02:00_22_01_2110_16006168                        131.785714   92.785714   \n",
       "17:21:00_30_01_2110_14816979                               NaN   96.173913   \n",
       "17:07:00_01_02_2110_13956717                         98.684211   80.157895   \n",
       "\n",
       "                              gender  race  age  \n",
       "formatted_time                                   \n",
       "13:45:00_11_01_2110_18106347       0     6   48  \n",
       "04:02:00_17_01_2110_18780420       1     7   84  \n",
       "02:02:00_22_01_2110_16006168       1     2   20  \n",
       "17:21:00_30_01_2110_14816979       1     7   30  \n",
       "17:07:00_01_02_2110_13956717       1     7   72  "
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_dataset.set_index(\"formatted_time\", inplace=True)\n",
    "df_dataset.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "04f330ec-93af-41d8-8dcd-361b8e1df2e4",
   "metadata": {},
   "source": [
    "## Impute BNP"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "29c0c1c7-e24c-45e7-961b-b3cb18289f8c",
   "metadata": {},
   "outputs": [],
   "source": [
    "import random\n",
    "# Function to generate random NT-proBNP values based on age\n",
    "def generate_nt_proBNP(age):\n",
    "    if age < 75:\n",
    "        return random.uniform(0, 125)  # For adults younger than 75 years\n",
    "    else:\n",
    "        return random.uniform(0, 450)  # For adults 75 years or older\n",
    "\n",
    "# Identify missing values in 'probnp'\n",
    "missing_values = df_dataset['bnp'].isnull()\n",
    "\n",
    "# Determine age of individuals with missing 'probnp' values (replace 'age_column' with the actual age column name)\n",
    "missing_age = df_dataset.loc[missing_values, 'age']\n",
    "\n",
    "# Generate random NT-proBNP values based on age\n",
    "imputed_values = missing_age.apply(generate_nt_proBNP)\n",
    "\n",
    "# Replace missing values in 'probnp' with generated values\n",
    "df_dataset.loc[missing_values, 'bnp'] = imputed_values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "d28f3c3f-b718-4f71-b3e4-086f5d9933ef",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>hf_original</th>\n",
       "      <th>hf_type_original</th>\n",
       "      <th>HDL</th>\n",
       "      <th>tot_cholesterol</th>\n",
       "      <th>glucose</th>\n",
       "      <th>bnp</th>\n",
       "      <th>Arterial Blood Pressure diastolic</th>\n",
       "      <th>Arterial Blood Pressure systolic</th>\n",
       "      <th>Heart Rate</th>\n",
       "      <th>gender</th>\n",
       "      <th>race</th>\n",
       "      <th>age</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>formatted_time</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>13:45:00_11_01_2110_18106347</th>\n",
       "      <td>0</td>\n",
       "      <td>Non-HF</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>95.000000</td>\n",
       "      <td>33.008375</td>\n",
       "      <td>66.068966</td>\n",
       "      <td>108.655172</td>\n",
       "      <td>100.800000</td>\n",
       "      <td>0</td>\n",
       "      <td>6</td>\n",
       "      <td>48</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>04:02:00_17_01_2110_18780420</th>\n",
       "      <td>0</td>\n",
       "      <td>Non-HF</td>\n",
       "      <td>56.0</td>\n",
       "      <td>159.0</td>\n",
       "      <td>113.000000</td>\n",
       "      <td>241.066127</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>59.958333</td>\n",
       "      <td>1</td>\n",
       "      <td>7</td>\n",
       "      <td>84</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>02:02:00_22_01_2110_16006168</th>\n",
       "      <td>0</td>\n",
       "      <td>Non-HF</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>96.142857</td>\n",
       "      <td>26.937602</td>\n",
       "      <td>80.428571</td>\n",
       "      <td>131.785714</td>\n",
       "      <td>92.785714</td>\n",
       "      <td>1</td>\n",
       "      <td>2</td>\n",
       "      <td>20</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17:21:00_30_01_2110_14816979</th>\n",
       "      <td>0</td>\n",
       "      <td>Non-HF</td>\n",
       "      <td>39.0</td>\n",
       "      <td>189.0</td>\n",
       "      <td>98.133333</td>\n",
       "      <td>92.589341</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>96.173913</td>\n",
       "      <td>1</td>\n",
       "      <td>7</td>\n",
       "      <td>30</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17:07:00_01_02_2110_13956717</th>\n",
       "      <td>0</td>\n",
       "      <td>Non-HF</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>106.777778</td>\n",
       "      <td>60.227202</td>\n",
       "      <td>52.473684</td>\n",
       "      <td>98.684211</td>\n",
       "      <td>80.157895</td>\n",
       "      <td>1</td>\n",
       "      <td>7</td>\n",
       "      <td>72</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                              hf_original hf_type_original   HDL  \\\n",
       "formatted_time                                                     \n",
       "13:45:00_11_01_2110_18106347            0           Non-HF   NaN   \n",
       "04:02:00_17_01_2110_18780420            0           Non-HF  56.0   \n",
       "02:02:00_22_01_2110_16006168            0           Non-HF   NaN   \n",
       "17:21:00_30_01_2110_14816979            0           Non-HF  39.0   \n",
       "17:07:00_01_02_2110_13956717            0           Non-HF   NaN   \n",
       "\n",
       "                              tot_cholesterol     glucose         bnp  \\\n",
       "formatted_time                                                          \n",
       "13:45:00_11_01_2110_18106347              NaN   95.000000   33.008375   \n",
       "04:02:00_17_01_2110_18780420            159.0  113.000000  241.066127   \n",
       "02:02:00_22_01_2110_16006168              NaN   96.142857   26.937602   \n",
       "17:21:00_30_01_2110_14816979            189.0   98.133333   92.589341   \n",
       "17:07:00_01_02_2110_13956717              NaN  106.777778   60.227202   \n",
       "\n",
       "                              Arterial Blood Pressure diastolic  \\\n",
       "formatted_time                                                    \n",
       "13:45:00_11_01_2110_18106347                          66.068966   \n",
       "04:02:00_17_01_2110_18780420                                NaN   \n",
       "02:02:00_22_01_2110_16006168                          80.428571   \n",
       "17:21:00_30_01_2110_14816979                                NaN   \n",
       "17:07:00_01_02_2110_13956717                          52.473684   \n",
       "\n",
       "                              Arterial Blood Pressure systolic  Heart Rate  \\\n",
       "formatted_time                                                               \n",
       "13:45:00_11_01_2110_18106347                        108.655172  100.800000   \n",
       "04:02:00_17_01_2110_18780420                               NaN   59.958333   \n",
       "02:02:00_22_01_2110_16006168                        131.785714   92.785714   \n",
       "17:21:00_30_01_2110_14816979                               NaN   96.173913   \n",
       "17:07:00_01_02_2110_13956717                         98.684211   80.157895   \n",
       "\n",
       "                              gender  race  age  \n",
       "formatted_time                                   \n",
       "13:45:00_11_01_2110_18106347       0     6   48  \n",
       "04:02:00_17_01_2110_18780420       1     7   84  \n",
       "02:02:00_22_01_2110_16006168       1     2   20  \n",
       "17:21:00_30_01_2110_14816979       1     7   30  \n",
       "17:07:00_01_02_2110_13956717       1     7   72  "
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_dataset.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ae428836-8773-403e-b453-744c4934b028",
   "metadata": {},
   "source": [
    "## Data splitting into train, validation, and test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "b66f4b88-fdd0-45b0-9371-452d0395a812",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "for HFpEF vs rest (no HFpEF)\n"
     ]
    }
   ],
   "source": [
    "print(\"for HFpEF vs rest (no HFpEF)\")\n",
    "\n",
    "X_id = df_dataset.index\n",
    "\n",
    "X = df_dataset[feature_list]\n",
    "y = df_dataset[\"hf_type_original\"]\n",
    "y = y.replace(\"HFpEF\", 1)\n",
    "y = y.replace(\"HFrEF\", 0)\n",
    "y = y.replace(\"Non-HF\", 0)\n",
    "\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3, random_state = 0, stratify = y)    \n",
    "\n",
    "X_train_id, X_test_id, _, _ = train_test_split(X_id, y, test_size = 0.3, random_state = 0, stratify = y)\n",
    "X_train_id, X_val_id, _, _ = train_test_split(X_train_id, y_train, test_size = 0.5, random_state = 0, stratify = y_train)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "d5186fec-3e41-4350-8101-fef3fc967b30",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "from sklearn.impute import SimpleImputer\n",
    "\n",
    "imputer = SimpleImputer(strategy=\"median\")\n",
    "X_train_imputed = imputer.fit_transform(X_train)\n",
    "X_test_imputed = imputer.transform(X_test)\n",
    "\n",
    "scaler = StandardScaler()\n",
    "X_train_scaled = scaler.fit_transform(X_train_imputed)\n",
    "X_test_scaled = scaler.transform(X_test_imputed)\n",
    "\n",
    "X_train_scaled_df = pd.DataFrame(X_train_scaled, columns=X.columns, index=X_train.index)\n",
    "X_test_scaled_df = pd.DataFrame(X_test_scaled, columns=X.columns, index=X_test.index)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "c8c60f32-7483-4635-bb1e-4ba017805326",
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train_scaled_df, X_val, y_train, y_val = train_test_split(X_train_scaled_df, y_train, test_size = 0.5, random_state = 0, stratify = y_train) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "e1f01e3b-ad83-4df9-872d-e0a0bee834ea",
   "metadata": {},
   "outputs": [],
   "source": [
    "base_dir = '/home/idies/workspace/SAFE/ecg_preprocessed'\n",
    "\n",
    "# Create the full file paths\n",
    "# waveform_files = [f for f in os.listdir(base_dir)]\n",
    "\n",
    "train_file_paths = [f\"{file_id}\" for file_id in X_train_id]\n",
    "val_file_paths = [f\"{file_id}\" for file_id in X_val_id]\n",
    "test_file_paths = [f\"{file_id}\" for file_id in X_test_id]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "236d87a1-7d96-4ce4-a538-daab1d0d686a",
   "metadata": {},
   "source": [
    "## Aligning waveform and tabular data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "a3e9d5f8-57fa-4409-9afe-ba3154c447fd",
   "metadata": {},
   "outputs": [],
   "source": [
    "def aligning_dataset(waveform_files, waveform_dir, tab_dataset_feature, tab_dataset_y):\n",
    "    waveform_paths = []\n",
    "    tabular_dat_list = []\n",
    "    label = []\n",
    "    \n",
    "    for i, waveform_file_name in enumerate(waveform_files):\n",
    "        patient_id = waveform_file_name\n",
    "        if patient_id in tab_dataset_feature.index:\n",
    "            waveform_paths.append(os.path.join(waveform_dir, patient_id))\n",
    "            tabular_dat_list.append(tab_dataset_feature.loc[patient_id].values)\n",
    "            # Assume labels are included in the tabular data\n",
    "            label.append(tab_dataset_y.loc[patient_id])\n",
    "\n",
    "    # Convert lists to numpy arrays\n",
    "    tabular_dat_arr = np.array(tabular_dat_list)\n",
    "    labels_arr = np.array(label)\n",
    "\n",
    "    return waveform_paths, tabular_dat_arr, labels_arr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "c84b2be4-ed1d-440e-86bd-427984c6d9c2",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "train_waveform_paths, train_tab_data, train_labels = aligning_dataset(train_file_paths,base_dir, X_train_scaled_df, y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "c7310524-6c6e-4221-88c3-5e947835c701",
   "metadata": {},
   "outputs": [],
   "source": [
    "train_waveform_paths, train_tab_data, train_labels = aligning_dataset(train_file_paths,base_dir, X_train_scaled_df, y_train)\n",
    "\n",
    "val_waveform_paths, val_tab_data, val_labels = aligning_dataset(val_file_paths,base_dir, X_val, y_val)\n",
    "\n",
    "test_waveform_paths, test_tab_data, test_labels = aligning_dataset(test_file_paths,base_dir, X_test_scaled_df, y_test)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a8e1c48f-8544-480c-830b-fadc1075f66c",
   "metadata": {},
   "source": [
    "## Create data generator and loader for NN"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "eea36574-c14c-4994-9ad8-f0af0268ab16",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Define the data generator\n",
    "def ecg_data_generator(waveform_paths, tabular_data, labels):\n",
    "    for i in range(len(waveform_paths)):\n",
    "        try:\n",
    "            # Load the waveform data from Parquet\n",
    "            waveform_data = pq.read_table(waveform_paths[i]).to_pandas().values  # Ensure it's a numpy array\n",
    "            tabular_data_sample = tabular_data[i]  # Corresponding tabular data\n",
    "            label = labels[i]\n",
    "            yield (waveform_data, tabular_data_sample), label\n",
    "        except Exception as e:\n",
    "            print(f'Error loading {waveform_paths[i]}: {e}')\n",
    "            continue\n",
    "\n",
    "# Create TensorFlow datasets\n",
    "def create_dataset(waveform_paths, tabular_data, labels, batch_size):\n",
    "    dataset = tf.data.Dataset.from_generator(\n",
    "        lambda: ecg_data_generator(waveform_paths, tabular_data, labels),\n",
    "        output_signature=(\n",
    "            (tf.TensorSpec(shape=(5000, 12), dtype=tf.float32), tf.TensorSpec(shape=(tabular_data.shape[1],), dtype=tf.float32)),\n",
    "            tf.TensorSpec(shape=(), dtype=tf.int32)\n",
    "        )\n",
    "    )\n",
    "    return dataset.batch(batch_size).prefetch(tf.data.AUTOTUNE).repeat()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "39b74925-ea29-4354-bf7b-86dd0ca0aac2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Shape of train_tab_data: (6414, 10)\n",
      "Shape of val_tab_data: (6414, 10)\n",
      "Shape of test_tab_data: (5499, 10)\n"
     ]
    }
   ],
   "source": [
    "print(\"Shape of train_tab_data:\", train_tab_data.shape)\n",
    "print(\"Shape of val_tab_data:\", val_tab_data.shape)\n",
    "print(\"Shape of test_tab_data:\", test_tab_data.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "7c7bd465-b211-485d-874d-4f68d4e356ba",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Shuffle and batch the dataset\n",
    "batch_size = 32\n",
    "\n",
    "train_dataset = create_dataset(train_waveform_paths,train_tab_data, train_labels, batch_size)\n",
    "\n",
    "val_dataset = create_dataset(val_waveform_paths,val_tab_data, val_labels, batch_size)\n",
    "\n",
    "test_dataset = create_dataset(test_waveform_paths,test_tab_data, test_labels, batch_size)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "c20fb053-5edb-4afb-bc44-f3f57dc8b267",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Waveform data shape: (32, 5000, 12)\n",
      "Waveform data: tf.Tensor(\n",
      "[[[ 0.     0.    -0.015 ...  0.02   0.02   0.025]\n",
      "  [ 0.    -0.01  -0.025 ...  0.035  0.02   0.025]\n",
      "  [ 0.    -0.02  -0.035 ...  0.035  0.02   0.025]\n",
      "  ...\n",
      "  [ 0.02   0.01  -0.025 ...  0.01   0.02   0.005]\n",
      "  [ 0.02   0.    -0.035 ...  0.015  0.02   0.005]\n",
      "  [ 0.02   0.    -0.035 ...  0.02   0.02   0.005]]\n",
      "\n",
      " [[ 0.     0.105  0.105 ...  0.015 -0.015 -0.02 ]\n",
      "  [ 0.     0.095  0.095 ...  0.035 -0.01  -0.02 ]\n",
      "  [ 0.005  0.085  0.08  ...  0.045 -0.01  -0.02 ]\n",
      "  ...\n",
      "  [-0.04  -0.015  0.025 ... -0.045 -0.075 -0.07 ]\n",
      "  [-0.035 -0.015  0.02  ... -0.045 -0.075 -0.07 ]\n",
      "  [-0.02  -0.015  0.005 ... -0.045 -0.075 -0.06 ]]\n",
      "\n",
      " [[ 0.025  0.025 -0.01  ...  0.     0.01   0.01 ]\n",
      "  [ 0.02   0.01  -0.02  ... -0.01   0.     0.01 ]\n",
      "  [ 0.005 -0.01  -0.025 ... -0.01   0.     0.015]\n",
      "  ...\n",
      "  [-0.045  0.035  0.07  ...  0.01  -0.01  -0.025]\n",
      "  [-0.03   0.04   0.06  ...  0.01  -0.01  -0.03 ]\n",
      "  [-0.015  0.045  0.05  ...  0.01  -0.01  -0.03 ]]\n",
      "\n",
      " ...\n",
      "\n",
      " [[-0.02  -0.03  -0.02  ... -0.05  -0.01  -0.025]\n",
      "  [-0.02  -0.045 -0.035 ... -0.045 -0.025 -0.02 ]\n",
      "  [-0.02  -0.045 -0.035 ... -0.04  -0.025 -0.02 ]\n",
      "  ...\n",
      "  [ 0.03   0.03  -0.01  ...  0.07   0.01   0.   ]\n",
      "  [ 0.05   0.045 -0.015 ...  0.07   0.02   0.015]\n",
      "  [ 0.06   0.05  -0.02  ...  0.07   0.03   0.035]]\n",
      "\n",
      " [[ 0.015  0.39   0.385 ...  0.04  -0.085 -0.035]\n",
      "  [ 0.015  0.39   0.385 ...  0.04  -0.075 -0.03 ]\n",
      "  [ 0.015  0.39   0.385 ...  0.04  -0.075 -0.03 ]\n",
      "  ...\n",
      "  [ 0.245  0.22  -0.015 ...  0.77   0.545  0.32 ]\n",
      "  [ 0.35   0.305 -0.035 ...  0.95   0.695  0.435]\n",
      "  [ 0.455  0.39  -0.055 ...  1.12   0.855  0.56 ]]\n",
      "\n",
      " [[ 0.04   0.025 -0.005 ...  0.025  0.02   0.03 ]\n",
      "  [ 0.04   0.035  0.005 ...  0.02   0.02   0.03 ]\n",
      "  [ 0.035  0.035  0.01  ...  0.02   0.02   0.025]\n",
      "  ...\n",
      "  [-0.01   0.005  0.025 ...  0.025  0.02  -0.005]\n",
      "  [-0.015 -0.005  0.02  ...  0.025  0.02  -0.005]\n",
      "  [-0.02  -0.015  0.015 ...  0.025  0.02  -0.01 ]]], shape=(32, 5000, 12), dtype=float32)\n",
      "Tabular data shape: (32, 10)\n",
      "Tabular data: tf.Tensor(\n",
      "[[-4.2283904e-02 -2.5075596e-02 -5.4158688e-01 -1.9829334e-01\n",
      "   2.6681125e-01 -4.0540612e-01 -3.4524041e-01  8.1872612e-01\n",
      "   1.0828635e-01 -3.1020245e-02]\n",
      " [-4.2283904e-02 -2.5075596e-02 -5.5976123e-01 -1.9883244e-01\n",
      "  -5.8732204e-02 -1.0781092e-01  1.5162169e+00  8.1872612e-01\n",
      "   6.7135781e-01 -4.1030002e-01]\n",
      " [-4.2283904e-02 -2.5075596e-02  2.6529076e+00 -2.1726634e-01\n",
      "  -1.2964766e+00 -1.6839484e+00  2.1560092e+00 -1.2214097e+00\n",
      "   1.0828635e-01  9.5406346e-02]\n",
      " [ 1.6452136e+00 -6.6213804e-01 -8.1193060e-01 -1.3647822e-01\n",
      "  -5.8732204e-02 -1.0781092e-01 -6.4225733e-01 -1.2214097e+00\n",
      "   6.7135781e-01  9.1717917e-01]\n",
      " [-4.2283904e-02 -2.5075596e-02 -5.2114069e-01 -2.1573868e-01\n",
      "  -5.8732204e-02 -1.0781092e-01  5.5379128e-01 -1.2214097e+00\n",
      "   6.7135781e-01  1.5861964e-01]\n",
      " [-4.2610273e+00 -1.5646431e+00 -2.0195341e-01  4.8127562e-02\n",
      "   8.4921259e-01 -1.8589728e-02 -8.0625910e-01 -1.2214097e+00\n",
      "   6.7135781e-01 -4.1030002e-01]\n",
      " [-4.2283904e-02 -2.5075596e-02  2.3470016e+00 -2.1253213e-01\n",
      "  -5.8732204e-02 -1.0781092e-01  1.7015917e+00 -1.2214097e+00\n",
      "   1.0828635e-01 -7.8957981e-01]\n",
      " [-4.2283904e-02 -2.5075596e-02  1.4874513e+00  3.0590134e+00\n",
      "  -5.8732204e-02 -1.0781092e-01  2.1814244e+00 -1.2214097e+00\n",
      "  -2.7070711e+00  6.0111272e-01]\n",
      " [-4.2283904e-02 -2.5075596e-02 -3.5359579e-01  2.3138530e+00\n",
      "  -5.8732204e-02 -1.0781092e-01 -2.0241041e+00  8.1872612e-01\n",
      "   6.7135781e-01  1.2332456e+00]\n",
      " [-4.2283904e-02 -2.5075596e-02 -4.7018757e-01 -1.4714882e-01\n",
      "  -1.0013020e+00  6.3277519e-01 -1.2727245e+00  8.1872612e-01\n",
      "   1.0828635e-01  7.2753930e-01]\n",
      " [-4.2283904e-02 -2.5075596e-02 -2.4489036e-01 -2.0005362e-01\n",
      "  -5.8732204e-02 -1.0781092e-01  6.9091791e-01 -1.2214097e+00\n",
      "   6.7135781e-01 -1.4849260e+00]\n",
      " [-4.2283904e-02 -2.5075596e-02  1.8619730e+00 -1.9508237e-01\n",
      "  -5.8732204e-02 -1.0781092e-01 -2.5119260e-01  8.1872612e-01\n",
      "   6.7135781e-01 -4.7351331e-01]\n",
      " [-4.2283904e-02 -2.5075596e-02  2.0791566e+00 -1.9428143e-01\n",
      "  -5.8732204e-02 -1.0781092e-01 -1.4033274e-01  8.1872612e-01\n",
      "  -2.7070711e+00  4.1147283e-01]\n",
      " [-4.2283904e-02 -4.9092207e+00  1.7923046e+00 -1.9366077e-01\n",
      "  -5.8732204e-02 -1.0781092e-01 -3.0530098e-01  8.1872612e-01\n",
      "   1.0828635e-01  3.4825954e-01]\n",
      " [-4.2283904e-02 -2.5075596e-02 -2.0536111e-01 -1.4614922e-01\n",
      "  -5.8732204e-02 -1.0781092e-01  2.6123831e+00 -1.2214097e+00\n",
      "   6.7135781e-01  1.1700324e+00]\n",
      " [-4.2283904e-02 -2.5075596e-02 -3.6541277e-01 -1.9756794e-01\n",
      "  -1.9685923e+00 -2.4808922e+00  3.5444987e-01  8.1872612e-01\n",
      "   1.0828635e-01  1.0436058e+00]\n",
      " [-4.2283904e-02 -2.5075596e-02  2.1157651e+00 -1.8555142e-01\n",
      "  -5.8732204e-02 -1.0781092e-01 -4.9735017e-02 -1.2214097e+00\n",
      "   6.7135781e-01  1.6125255e+00]\n",
      " [-4.2283904e-02 -2.5075596e-02 -1.8900418e-01  1.1117424e-01\n",
      "  -5.8732204e-02 -1.0781092e-01  3.8029712e-01  8.1872612e-01\n",
      "   6.7135781e-01 -1.2320728e+00]\n",
      " [-4.2283904e-02 -2.5075596e-02 -1.2701486e-01 -2.0185643e-01\n",
      "   4.4699132e-01 -7.4026126e-01  1.9795664e-02  8.1872612e-01\n",
      "  -2.7070711e+00 -4.7351331e-01]\n",
      " [-4.2283904e-02 -2.5075596e-02  8.4875214e-01 -2.1924694e-01\n",
      "   6.4134699e-01 -2.5945726e-01  9.6072721e-01  8.1872612e-01\n",
      "   1.0828635e-01 -7.8957981e-01]\n",
      " [-4.2283904e-02 -2.5075596e-02  1.2731287e-02 -1.6397418e-01\n",
      "  -7.9088312e-01 -8.4481084e-01 -4.4603243e-01 -1.2214097e+00\n",
      "   6.7135781e-01  1.1068190e+00]\n",
      " [-4.2283904e-02 -2.5075596e-02 -1.4321308e+00 -1.9637878e-01\n",
      "  -2.1938924e-01  7.4962485e-01 -1.5919861e+00  8.1872612e-01\n",
      "   1.0828635e-01 -2.2066014e-01]\n",
      " [-4.2283904e-02 -2.5075596e-02 -2.6897138e-01  1.1759884e+00\n",
      "  -1.7190692e+00 -6.8938309e-01 -2.9838279e-01 -1.2214097e+00\n",
      "   1.0828635e-01  9.8039246e-01]\n",
      " [-4.2283904e-02 -2.5075596e-02  4.5279255e+00 -2.1035372e-01\n",
      "  -2.5787678e+00  3.3568484e-01 -2.7925605e-01  8.1872612e-01\n",
      "   1.0828635e-01 -4.7351331e-01]\n",
      " [-4.2283904e-02 -2.5075596e-02 -6.3700229e-01 -2.2104904e-01\n",
      "  -5.8732204e-02 -1.0781092e-01  5.8635515e-01  8.1872612e-01\n",
      "  -2.7070711e+00 -8.5279310e-01]\n",
      " [-4.2283904e-02 -2.5075596e-02  4.7617763e-01 -1.9923267e-01\n",
      "  -5.8732204e-02 -1.0781092e-01  1.2661092e-01 -1.2214097e+00\n",
      "   1.0828635e-01  1.2964590e+00]\n",
      " [-4.2283904e-02 -2.5075596e-02  1.4536989e+00 -1.8407039e-01\n",
      "  -5.8732204e-02 -1.0781092e-01 -5.8817792e-01  8.1872612e-01\n",
      "  -2.7070711e+00  6.0111272e-01]\n",
      " [-4.2283904e-02 -2.5075596e-02 -1.2357646e-01 -1.9320582e-01\n",
      "  -1.9893653e-03 -1.5810475e+00 -5.8935356e-01  8.1872612e-01\n",
      "  -2.7070711e+00  3.2193050e-02]\n",
      " [-4.2283904e-02 -2.5075596e-02 -5.2159506e-01  4.0965721e-01\n",
      "  -5.8732204e-02 -1.0781092e-01  3.9888903e-01 -1.2214097e+00\n",
      "  -2.7070711e+00 -5.3672659e-01]\n",
      " [-4.2283904e-02 -2.5075596e-02  1.0759317e+00 -1.6233540e-01\n",
      "  -5.8732204e-02 -1.0781092e-01 -3.0275309e-01 -1.2214097e+00\n",
      "   6.7135781e-01  1.9285920e+00]\n",
      " [-4.2283904e-02 -2.5075596e-02 -2.0233205e-01 -1.7467177e-01\n",
      "   9.9790263e-01 -3.8568550e-01 -4.0220645e-01  8.1872612e-01\n",
      "   1.0828635e-01  6.0111272e-01]\n",
      " [-4.2283904e-02 -2.5075596e-02  2.2644578e-02  9.9076718e-02\n",
      "  -7.8612991e-02 -6.3539243e-01  2.0509520e+00 -1.2214097e+00\n",
      "   1.0828635e-01 -8.5279310e-01]], shape=(32, 10), dtype=float32)\n",
      "Label data shape: (32,)\n",
      "Label data: tf.Tensor([0 0 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0], shape=(32,), dtype=int32)\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2024-06-20 22:28:08.280939: W tensorflow/core/framework/local_rendezvous.cc:404] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence\n"
     ]
    }
   ],
   "source": [
    "# Inspect the data inside the train_dataset\n",
    "for (waveform, tabular), label in val_dataset.take(1):  # Only take the first batch for inspection\n",
    "    print(\"Waveform data shape:\", waveform.shape)\n",
    "    print(\"Waveform data:\", waveform)\n",
    "    print(\"Tabular data shape:\", tabular.shape)\n",
    "    print(\"Tabular data:\", tabular)\n",
    "    print(\"Label data shape:\", label.shape)\n",
    "    print(\"Label data:\", label)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c0049dc8-7c67-4c54-becc-1c4f4f777a4e",
   "metadata": {},
   "source": [
    "# Define model architecture"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "336ece76",
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "from keras import backend as K\n",
    "from keras.layers import (Input, Dense, Conv1D, Dropout, MaxPooling1D, \n",
    "                          Activation, Lambda, BatchNormalization, Add,\n",
    "                          Flatten, Attention, MultiHeadAttention)\n",
    "from keras.optimizers import Adam\n",
    "from keras.models import Model\n",
    "from keras.metrics import AUC\n",
    "from keras.models import Model, Sequential\n",
    "\n",
    "from tensorflow.keras.layers import Input, Conv1D, BatchNormalization, Conv2D, MaxPooling2D, \\\n",
    "    ReLU, Reshape, GlobalAveragePooling1D, Dense, Concatenate, Dropout, concatenate, LeakyReLU, SpatialDropout1D, Attention\n",
    "import logging\n",
    "from tensorflow.keras.layers import Layer, Dense, MultiHeadAttention, LayerNormalization\n",
    "\n",
    "# PAPER: Screening for cardiac contractile dysfunction using an artificial intelligence–enabled electrocardiogram\n",
    "#        https://www.nature.com/articles/s41591-018-0240-2\n",
    "# SOURCE REPO: https://github.com/chrisby/DeepCardiology\n",
    "class Attia_et_al_CNN():\n",
    "    def __init__(self, \n",
    "                 filter_numbers=[16, 16, 32, 32, 64, 64], \n",
    "                 kernel_widths=[7, 7, 5, 5, 3, 3], \n",
    "                 pool_sizes=[2, 2, 4, 2, 2, 4], \n",
    "                 spatial_num_filters=64, \n",
    "                 dense_dropout_rate=0.2, \n",
    "                 spatial_dropout_rate=0.2,\n",
    "                 dense_units=[64, 32], \n",
    "                 use_spatial_layer=False,\n",
    "                 verbose=1,\n",
    "                 use_residual=True):\n",
    "\n",
    "        self.filter_numbers = filter_numbers\n",
    "        self.kernel_widths = kernel_widths\n",
    "        self.pool_sizes = pool_sizes\n",
    "        self.spatial_num_filters = spatial_num_filters\n",
    "        self.dense_dropout_rate = dense_dropout_rate\n",
    "        self.spatial_dropout_rate = spatial_dropout_rate\n",
    "        self.dense_units = dense_units\n",
    "        self.use_spatial_layer = use_spatial_layer\n",
    "        self.verbose = verbose\n",
    "        self.use_residual = use_residual\n",
    "\n",
    "        self.att = Attention()\n",
    "\n",
    "        self.model = None\n",
    "\n",
    "        if self.verbose == 0:\n",
    "            return\n",
    "        \n",
    "        print(\"Attia et al. CNN model initialized with the following parameters:\")\n",
    "        print(f\"  filter_numbers: {self.filter_numbers}\")\n",
    "        print(f\"  kernel_widths: {self.kernel_widths}\")\n",
    "        print(f\"  pool_sizes: {self.pool_sizes}\")\n",
    "        print(f\"  spatial_num_filters: {self.spatial_num_filters}\")\n",
    "        print(f\"  dense_dropout_rate: {self.dense_dropout_rate}\")\n",
    "        print(f\"  spatial_dropout_rate: {self.spatial_dropout_rate}\")\n",
    "        print(f\"  dense_units: {self.dense_units}\")\n",
    "        print(f\"  use_spatial_layer: {self.use_spatial_layer}\")\n",
    "        print(f\"  use_residual: {self.use_residual}\")\n",
    "    \n",
    "    def get_temporal_layer(self, N, k, p, input_layer):\n",
    "        c = Conv1D(N, k, padding='same', kernel_initializer='he_normal')(input_layer)\n",
    "        b = tf.keras.layers.BatchNormalization()(c)\n",
    "        a = Activation('relu')(b)\n",
    "        p = MaxPooling1D(pool_size=p)(a)\n",
    "        do = SpatialDropout1D(self.spatial_dropout_rate)(p)\n",
    "        return do\n",
    "\n",
    "    def get_temporal_layer_with_residual(self, N, k, p, input_layer):\n",
    "        # Main pathway\n",
    "        x = Conv1D(N, k, padding='same', kernel_initializer='he_normal')(input_layer)\n",
    "        x = SpatialDropout1D(self.spatial_dropout_rate)(x)\n",
    "        x = BatchNormalization()(x)\n",
    "        x = Activation('relu')(x)\n",
    "        \n",
    "        # Shortcut pathway\n",
    "        # Ensure the shortcut matches the dimension of the main pathway's output, adjust filters and stride as necessary\n",
    "        shortcut = Conv1D(N, 1, padding='same', kernel_initializer='he_normal')(input_layer)  # 1x1 conv for matching dimension\n",
    "        shortcut = BatchNormalization()(shortcut)  # Optional, for matching feature-wise statistics\n",
    "        \n",
    "        # Merging the shortcut with the main pathway\n",
    "        merged_output = Add()([x, shortcut])  # Element-wise addition\n",
    "\n",
    "        x = MaxPooling1D(pool_size=p)(merged_output)\n",
    "        \n",
    "        return x\n",
    "    \n",
    "    def get_spatial_layer(self, kernel_size, input_layer):\n",
    "        c = Conv1D(self.spatial_num_filters, kernel_size, padding='same', data_format=\"channels_first\", kernel_initializer='he_normal')(input_layer)\n",
    "        b = tf.keras.layers.BatchNormalization()(c)\n",
    "        a = Activation('relu')(b)\n",
    "        do = SpatialDropout1D(self.spatial_dropout_rate)(a)\n",
    "        return do\n",
    "    \n",
    "    def get_fully_connected_layer(self, units, input_layer):\n",
    "        d = Dense(units, kernel_initializer='he_normal')(input_layer)\n",
    "        b = tf.keras.layers.BatchNormalization()(d)\n",
    "        a = Activation('relu')(b)\n",
    "        do = Dropout(self.dense_dropout_rate)(a)\n",
    "        return do\n",
    "\n",
    "    def build(self, input_shape=(5000, 12)):\n",
    "        input_layer = Input(shape=input_shape)\n",
    "        last_layer = input_layer\n",
    "        \n",
    "        for i in range(len(self.pool_sizes)):\n",
    "            if self.use_residual:\n",
    "                temp_layer = self.get_temporal_layer_with_residual(self.filter_numbers[i], self.kernel_widths[i],\n",
    "                                            self.pool_sizes[i], last_layer)\n",
    "            else:\n",
    "                temp_layer = self.get_temporal_layer(self.filter_numbers[i], self.kernel_widths[i],\n",
    "                                            self.pool_sizes[i], last_layer)\n",
    "            last_layer = temp_layer\n",
    "        \n",
    "        if self.use_spatial_layer:\n",
    "            last_layer = self.get_spatial_layer(input_shape[1], last_layer)\n",
    "\n",
    "        last_layer = Flatten()(last_layer)\n",
    "\n",
    "        for i in range(len(self.dense_units)):\n",
    "            dense_layer = self.get_fully_connected_layer(self.dense_units[i], last_layer)\n",
    "            last_layer = dense_layer\n",
    "\n",
    "        output_layer = Dense(1, activation='sigmoid')(last_layer)\n",
    "        self.model = Model(inputs=input_layer, outputs=output_layer)\n",
    "\n",
    "        if self.verbose > 0:\n",
    "            print(self.model.summary())\n",
    "        return self.model\n",
    "\n",
    "class MultiHeadCrossAttention(Layer):\n",
    "    def __init__(self, embed_dim, num_heads):\n",
    "        super().__init__()\n",
    "        self.cross_attention = MultiHeadAttention(num_heads=num_heads, key_dim=embed_dim)\n",
    "        self.dense_proj = Dense(embed_dim, activation='relu')\n",
    "        self.layer_norm = LayerNormalization(epsilon=1e-6)\n",
    "\n",
    "        # Project input dimensions to match expected [batch_size, sequence_length, embed_dim]\n",
    "        self.query_projection = Dense(embed_dim)\n",
    "        self.value_projection = Dense(embed_dim)\n",
    "\n",
    "    def call(self, query, value):\n",
    "        # Ensure query and value match required shape [batch_size, seq_length, embed_dim]\n",
    "        query = self.query_projection(tf.expand_dims(query, axis=1))\n",
    "        value = self.value_projection(tf.expand_dims(value, axis=1))\n",
    "\n",
    "        attn_output = self.cross_attention(query=query, value=value, key=value)\n",
    "        attn_output = self.dense_proj(attn_output[:, 0, :])  # Reshape output if needed\n",
    "        output = self.layer_norm(query[:, 0, :] + attn_output)\n",
    "\n",
    "        return output\n",
    "    \n",
    "# PAPER: Screening for cardiac contractile dysfunction using an artificial intelligence–enabled electrocardiogram\n",
    "#        https://www.nature.com/articles/s41591-018-0240-2\n",
    "# SOURCE REPO: https://github.com/chrisby/DeepCardiology\n",
    "class Attia_et_al_fusion():\n",
    "    def __init__(self, \n",
    "                 filter_numbers=[16, 16, 32, 32, 64, 64], \n",
    "                 kernel_widths=[5, 5, 5, 3, 3, 3], \n",
    "                 pool_sizes=[2, 2, 4, 2, 2, 4], \n",
    "                 spatial_num_filters=64, \n",
    "                 dropout_rate=0.2, \n",
    "                 dense_units=[64, 32], \n",
    "                 fusion_strategy=\"concat\",\n",
    "                 use_waveforms=True,\n",
    "                 use_residual = True,\n",
    "                 spatial_dropout_rate=0.2,\n",
    "                 verbose=1):\n",
    "        \n",
    "        # Fusion strategy options\n",
    "        # concat, self_attn, cross_attn\n",
    "        # mlp, tab_mlp\n",
    "        \n",
    "        self.filter_numbers = filter_numbers\n",
    "        self.kernel_widths = kernel_widths\n",
    "        self.pool_sizes = pool_sizes\n",
    "        self.spatial_num_filters = spatial_num_filters\n",
    "        self.dropout_rate = dropout_rate\n",
    "        self.dense_units = dense_units\n",
    "        self.fusion_strategy = fusion_strategy\n",
    "        self.use_waveforms = use_waveforms\n",
    "        self.use_residual = use_residual\n",
    "        self.spatial_dropout_rate = spatial_dropout_rate\n",
    "\n",
    "        self.verbose = verbose\n",
    "\n",
    "        self.model = None\n",
    "\n",
    "        self.att = Attention()\n",
    "\n",
    "        if self.verbose == 0:\n",
    "            return\n",
    "        \n",
    "        print(\"Attia et al. CNN model initialized with the following parameters:\")\n",
    "        print(f\"  filter_numbers: {self.filter_numbers}\")\n",
    "        print(f\"  kernel_widths: {self.kernel_widths}\")\n",
    "        print(f\"  pool_sizes: {self.pool_sizes}\")\n",
    "        print(f\"  spatial_num_filters: {self.spatial_num_filters}\")\n",
    "        print(f\"  dropout_rate: {self.dropout_rate}\")\n",
    "        print(f\"  dense_units: {self.dense_units}\")\n",
    "        print(f\"  fusion_strategy: {self.fusion_strategy}\")\n",
    "        print(f\"  use_waveforms: {self.use_waveforms}\")\n",
    "        print(f\"  use_residual: {self.use_residual}\")\n",
    "\n",
    "\n",
    "    def create_mlp(self, input_shape):\n",
    "        mlp = tf.keras.Sequential([Dense(128, input_shape=(40,), activation='relu'),\n",
    "                    Dropout(self.dropout_rate),\n",
    "                    Dense(32, activation='relu'),\n",
    "                    Dropout(self.dropout_rate),\n",
    "                    Dense(8, activation='relu'),\n",
    "                    Dropout(self.dropout_rate),\n",
    "                    Dense(1, activation='sigmoid')])\n",
    "        return mlp\n",
    "\n",
    "    def create_attn(self, input_shape):\n",
    "        attn = Attention()\n",
    "        return attn\n",
    "\n",
    "    def get_temporal_layer(self, N, k, p, input_layer):\n",
    "        c = Conv1D(N, k, padding='same')(input_layer)\n",
    "        # c = SeparableConv1D(N, k, padding='same', activation='relu')(input_layer)\n",
    "        b = tf.keras.layers.BatchNormalization()(c)\n",
    "        a = Activation('relu')(b)\n",
    "        p = MaxPooling1D(pool_size=p)(a)\n",
    "        do = SpatialDropout1D(0.1)(p)\n",
    "        return do\n",
    "    \n",
    "    def get_temporal_layer_with_residual(self, N, k, p, input_layer):\n",
    "        # Main pathway\n",
    "        x = Conv1D(N, k, padding='same', kernel_initializer='he_normal')(input_layer)\n",
    "        x = SpatialDropout1D(self.spatial_dropout_rate)(x)\n",
    "        x = BatchNormalization()(x)\n",
    "        x = Activation('relu')(x)\n",
    "        \n",
    "        # Shortcut pathway\n",
    "        # Ensure the shortcut matches the dimension of the main pathway's output, adjust filters and stride as necessary\n",
    "        shortcut = Conv1D(N, 1, padding='same', kernel_initializer='he_normal')(input_layer)  # 1x1 conv for matching dimension\n",
    "        shortcut = BatchNormalization()(shortcut)  # Optional, for matching feature-wise statistics\n",
    "        \n",
    "        # Merging the shortcut with the main pathway\n",
    "        merged_output = Add()([x, shortcut])  # Element-wise addition\n",
    "\n",
    "        x = MaxPooling1D(pool_size=p)(merged_output)\n",
    "        \n",
    "        return x\n",
    "    \n",
    "    def get_spatial_layer(self, kernel_size, input_layer):\n",
    "        c = Conv1D(self.spatial_num_filters, kernel_size, kernel_initializer='he_normal')(input_layer)\n",
    "        # c = Conv1D(self.spatial_num_filters, kernel_size, data_format=\"channels_first\", kernel_initializer='he_normal')(input_layer)\n",
    "        b = tf.keras.layers.BatchNormalization()(c)\n",
    "        a = Activation('relu')(b)\n",
    "        do = SpatialDropout1D(0.1)(a)\n",
    "        return do\n",
    "\n",
    "    def build(self, input_shape=(5000, 12), fusion_shape=(1,)):\n",
    "        waveform_input = Input(shape=input_shape)\n",
    "        last_layer = waveform_input\n",
    "        \n",
    "        # Building CNN layers for waveform processing\n",
    "        for i in range(len(self.pool_sizes)):\n",
    "            if self.use_residual:\n",
    "                temp_layer = self.get_temporal_layer_with_residual(self.filter_numbers[i], self.kernel_widths[i],\n",
    "                                            self.pool_sizes[i], last_layer)\n",
    "            else:\n",
    "                temp_layer = self.get_temporal_layer(self.filter_numbers[i], self.kernel_widths[i],\n",
    "                                            self.pool_sizes[i], last_layer)\n",
    "            last_layer = temp_layer\n",
    "        \n",
    "        # last_layer = self.get_spatial_layer(input_shape[1], last_layer)\n",
    "        flattened_waveform = Flatten()(last_layer)\n",
    "\n",
    "        # Final Dense layers\n",
    "        x = Dense(64, activation='relu')(flattened_waveform)\n",
    "        x = Dropout(self.dropout_rate)(x)\n",
    "        x = Dense(32, activation='relu')(x)\n",
    "        x = Dropout(self.dropout_rate)(x)\n",
    "\n",
    "        fusion_input = Input(shape=fusion_shape)\n",
    "        # f = Dense(32, activation='relu')(fusion_input)\n",
    "        # f = Dropout(self.dropout_rate)(f)\n",
    "        # f = Dense(16, activation='relu')(f)\n",
    "        # f = Dropout(self.dropout_rate)(f)\n",
    "\n",
    "        if self.use_waveforms:\n",
    "            if self.fusion_strategy == \"concat\":\n",
    "                x = concatenate([x, fusion_input])\n",
    "                output = Dense(1, activation='sigmoid')(x)\n",
    "            \n",
    "            elif self.fusion_strategy == \"self_attn\":\n",
    "                # fusion_input = Dropout(self.dropout_rate)(fusion_input)\n",
    "                x = concatenate([x, fusion_input])\n",
    "\n",
    "                embed_dim = 16  # Dimensionality of the encoder.\n",
    "                num_heads = 4    # Number of attention heads.\n",
    "\n",
    "                cross_attention_layer = MultiHeadCrossAttention(embed_dim, num_heads)\n",
    "                x = cross_attention_layer(x, x)\n",
    "                x = Dropout(self.dropout_rate)(x)\n",
    "                output = Dense(1, activation='sigmoid')(x)\n",
    "\n",
    "            elif self.fusion_strategy == \"cross_attn\":\n",
    "                embed_dim = 16  # Dimensionality of the encoder.\n",
    "                num_heads = 4    # Number of attention heads.\n",
    "\n",
    "                cross_attention_layer = MultiHeadCrossAttention(embed_dim, num_heads)\n",
    "\n",
    "                # fusion_input = Dropout(self.dropout_rate)(fusion_input)\n",
    "                x = cross_attention_layer(x, fusion_input)\n",
    "                x = Dropout(self.dropout_rate)(x)\n",
    "                output = Dense(1, activation='sigmoid')(x)\n",
    "\n",
    "            if self.fusion_strategy == \"mlp\":\n",
    "                x = concatenate([x, fusion_input])\n",
    "                # WF/tab concat -> MLP -> output\n",
    "                x = Dense(32, activation='relu')(x)\n",
    "                x = Dropout(self.dropout_rate)(x)\n",
    "                x = Dense(16, activation='relu')(x)\n",
    "                x = Dropout(self.dropout_rate)(x)\n",
    "                x = Dense(8, activation='relu')(x)\n",
    "                x = Dropout(self.dropout_rate)(x)\n",
    "                output = Dense(1, activation='sigmoid')(x)\n",
    "\n",
    "            elif self.fusion_strategy == \"tab_mlp\":\n",
    "                x = Dense(16, activation='relu')(x)\n",
    "                x = Dropout(self.dropout_rate)(x)\n",
    "\n",
    "                fus = Dense(32, activation='relu')(fusion_input)\n",
    "                fus = Dropout(self.dropout_rate)(fus)\n",
    "                fus = Dense(16, activation='relu')(fus)\n",
    "                fus = Dropout(self.dropout_rate)(fus)\n",
    "\n",
    "                x = concatenate([x, fus])\n",
    "                output = Dense(1, activation='sigmoid')(x)\n",
    "        else:\n",
    "            x = fusion_input\n",
    "            output = Dense(1, activation='sigmoid')(x)\n",
    "\n",
    "            # x = Dense(16, activation='relu')(x)\n",
    "            # x = Dropout(self.dropout_rate)(x)\n",
    "            # x = Dense(8, activation='relu')(x)\n",
    "            # x = Dropout(self.dropout_rate)(x)\n",
    "\n",
    "        # x = Dense(16, activation='relu')(x)\n",
    "        # x = Dropout(self.dropout_rate)(x)\n",
    "        # x = concatenate([x, f])\n",
    "        # x = Dense(8, activation='relu')(x)\n",
    "\n",
    "        # WF/tab concat -> MLP -> output\n",
    "        # x = Dense(32, activation='relu')(x)\n",
    "        # x = Dropout(self.dropout_rate)(x)\n",
    "        # x = Dense(16, activation='relu')(x)\n",
    "        # x = Dropout(self.dropout_rate)(x)\n",
    "        # x = Dense(8, activation='relu')(x)\n",
    "        # x = Dropout(self.dropout_rate)(x)\n",
    "\n",
    "\n",
    "        # WF/tab concat -> attn -> output\n",
    "        # x = self.att([x, x])\n",
    "        # output = Dense(1, activation='sigmoid')(x)\n",
    "\n",
    "        self.model = Model(inputs=[waveform_input, fusion_input], outputs=output)\n",
    "\n",
    "        if self.verbose > 0:\n",
    "            print(self.model.summary())\n",
    "\n",
    "        return self.model\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "704be88b-c1b6-457b-970b-af3354676408",
   "metadata": {},
   "source": [
    "# Model training and evaluation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "74d8e183-4a5b-42ff-9a96-726282992106",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Calculate steps per epoch\n",
    "steps_per_epoch = len(train_waveform_paths) // batch_size\n",
    "validation_steps = len(val_waveform_paths) // batch_size\n",
    "test_steps = len(test_waveform_paths) // batch_size\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "9f2d727e-3d36-4994-afd4-688b33512086",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Attia et al. CNN model initialized with the following parameters:\n",
      "  filter_numbers: [16, 16, 32, 32, 64, 64]\n",
      "  kernel_widths: [5, 5, 5, 3, 3, 3]\n",
      "  pool_sizes: [2, 2, 4, 2, 2, 4]\n",
      "  spatial_num_filters: 64\n",
      "  dropout_rate: 0.2\n",
      "  dense_units: [64, 32]\n",
      "  fusion_strategy: concat\n",
      "  use_waveforms: True\n",
      "  use_residual: True\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">Model: \"functional_1\"</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1mModel: \"functional_1\"\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓\n",
       "┃<span style=\"font-weight: bold\"> Layer (type)        </span>┃<span style=\"font-weight: bold\"> Output Shape      </span>┃<span style=\"font-weight: bold\">    Param # </span>┃<span style=\"font-weight: bold\"> Connected to      </span>┃\n",
       "┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩\n",
       "│ input_layer         │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">5000</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">12</span>)  │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ -                 │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">InputLayer</span>)        │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv1D</span>)     │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">5000</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">16</span>)  │        <span style=\"color: #00af00; text-decoration-color: #00af00\">976</span> │ input_layer[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>] │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ spatial_dropout1d   │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">5000</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">16</span>)  │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ conv1d[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]      │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">SpatialDropout1D</span>)  │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ batch_normalization │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">5000</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">16</span>)  │         <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span> │ spatial_dropout1… │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">BatchNormalizatio…</span> │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_1 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv1D</span>)   │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">5000</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">16</span>)  │        <span style=\"color: #00af00; text-decoration-color: #00af00\">208</span> │ input_layer[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>] │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ activation          │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">5000</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">16</span>)  │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ batch_normalizat… │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Activation</span>)        │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ batch_normalizatio… │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">5000</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">16</span>)  │         <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span> │ conv1d_1[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]    │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">BatchNormalizatio…</span> │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ add (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Add</span>)           │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">5000</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">16</span>)  │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ activation[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>], │\n",
       "│                     │                   │            │ batch_normalizat… │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ max_pooling1d       │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">2500</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">16</span>)  │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ add[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]         │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">MaxPooling1D</span>)      │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_2 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv1D</span>)   │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">2500</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">16</span>)  │      <span style=\"color: #00af00; text-decoration-color: #00af00\">1,296</span> │ max_pooling1d[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]… │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ spatial_dropout1d_1 │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">2500</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">16</span>)  │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ conv1d_2[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]    │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">SpatialDropout1D</span>)  │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ batch_normalizatio… │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">2500</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">16</span>)  │         <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span> │ spatial_dropout1… │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">BatchNormalizatio…</span> │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_3 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv1D</span>)   │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">2500</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">16</span>)  │        <span style=\"color: #00af00; text-decoration-color: #00af00\">272</span> │ max_pooling1d[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]… │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ activation_1        │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">2500</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">16</span>)  │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ batch_normalizat… │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Activation</span>)        │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ batch_normalizatio… │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">2500</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">16</span>)  │         <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span> │ conv1d_3[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]    │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">BatchNormalizatio…</span> │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ add_1 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Add</span>)         │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">2500</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">16</span>)  │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ activation_1[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">…</span> │\n",
       "│                     │                   │            │ batch_normalizat… │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ max_pooling1d_1     │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">1250</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">16</span>)  │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ add_1[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]       │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">MaxPooling1D</span>)      │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_4 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv1D</span>)   │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">1250</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>)  │      <span style=\"color: #00af00; text-decoration-color: #00af00\">2,592</span> │ max_pooling1d_1[<span style=\"color: #00af00; text-decoration-color: #00af00\">…</span> │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ spatial_dropout1d_2 │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">1250</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>)  │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ conv1d_4[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]    │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">SpatialDropout1D</span>)  │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ batch_normalizatio… │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">1250</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>)  │        <span style=\"color: #00af00; text-decoration-color: #00af00\">128</span> │ spatial_dropout1… │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">BatchNormalizatio…</span> │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_5 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv1D</span>)   │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">1250</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>)  │        <span style=\"color: #00af00; text-decoration-color: #00af00\">544</span> │ max_pooling1d_1[<span style=\"color: #00af00; text-decoration-color: #00af00\">…</span> │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ activation_2        │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">1250</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>)  │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ batch_normalizat… │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Activation</span>)        │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ batch_normalizatio… │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">1250</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>)  │        <span style=\"color: #00af00; text-decoration-color: #00af00\">128</span> │ conv1d_5[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]    │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">BatchNormalizatio…</span> │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ add_2 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Add</span>)         │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">1250</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>)  │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ activation_2[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">…</span> │\n",
       "│                     │                   │            │ batch_normalizat… │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ max_pooling1d_2     │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">312</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>)   │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ add_2[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]       │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">MaxPooling1D</span>)      │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_6 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv1D</span>)   │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">312</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>)   │      <span style=\"color: #00af00; text-decoration-color: #00af00\">3,104</span> │ max_pooling1d_2[<span style=\"color: #00af00; text-decoration-color: #00af00\">…</span> │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ spatial_dropout1d_3 │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">312</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>)   │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ conv1d_6[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]    │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">SpatialDropout1D</span>)  │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ batch_normalizatio… │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">312</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>)   │        <span style=\"color: #00af00; text-decoration-color: #00af00\">128</span> │ spatial_dropout1… │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">BatchNormalizatio…</span> │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_7 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv1D</span>)   │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">312</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>)   │      <span style=\"color: #00af00; text-decoration-color: #00af00\">1,056</span> │ max_pooling1d_2[<span style=\"color: #00af00; text-decoration-color: #00af00\">…</span> │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ activation_3        │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">312</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>)   │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ batch_normalizat… │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Activation</span>)        │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ batch_normalizatio… │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">312</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>)   │        <span style=\"color: #00af00; text-decoration-color: #00af00\">128</span> │ conv1d_7[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]    │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">BatchNormalizatio…</span> │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ add_3 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Add</span>)         │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">312</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>)   │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ activation_3[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">…</span> │\n",
       "│                     │                   │            │ batch_normalizat… │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ max_pooling1d_3     │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">156</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>)   │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ add_3[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]       │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">MaxPooling1D</span>)      │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_8 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv1D</span>)   │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">156</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>)   │      <span style=\"color: #00af00; text-decoration-color: #00af00\">6,208</span> │ max_pooling1d_3[<span style=\"color: #00af00; text-decoration-color: #00af00\">…</span> │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ spatial_dropout1d_4 │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">156</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>)   │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ conv1d_8[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]    │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">SpatialDropout1D</span>)  │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ batch_normalizatio… │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">156</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>)   │        <span style=\"color: #00af00; text-decoration-color: #00af00\">256</span> │ spatial_dropout1… │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">BatchNormalizatio…</span> │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_9 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv1D</span>)   │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">156</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>)   │      <span style=\"color: #00af00; text-decoration-color: #00af00\">2,112</span> │ max_pooling1d_3[<span style=\"color: #00af00; text-decoration-color: #00af00\">…</span> │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ activation_4        │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">156</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>)   │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ batch_normalizat… │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Activation</span>)        │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ batch_normalizatio… │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">156</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>)   │        <span style=\"color: #00af00; text-decoration-color: #00af00\">256</span> │ conv1d_9[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]    │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">BatchNormalizatio…</span> │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ add_4 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Add</span>)         │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">156</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>)   │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ activation_4[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">…</span> │\n",
       "│                     │                   │            │ batch_normalizat… │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ max_pooling1d_4     │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">78</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>)    │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ add_4[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]       │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">MaxPooling1D</span>)      │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_10 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv1D</span>)  │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">78</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>)    │     <span style=\"color: #00af00; text-decoration-color: #00af00\">12,352</span> │ max_pooling1d_4[<span style=\"color: #00af00; text-decoration-color: #00af00\">…</span> │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ spatial_dropout1d_5 │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">78</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>)    │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ conv1d_10[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]   │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">SpatialDropout1D</span>)  │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ batch_normalizatio… │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">78</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>)    │        <span style=\"color: #00af00; text-decoration-color: #00af00\">256</span> │ spatial_dropout1… │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">BatchNormalizatio…</span> │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_11 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv1D</span>)  │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">78</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>)    │      <span style=\"color: #00af00; text-decoration-color: #00af00\">4,160</span> │ max_pooling1d_4[<span style=\"color: #00af00; text-decoration-color: #00af00\">…</span> │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ activation_5        │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">78</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>)    │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ batch_normalizat… │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Activation</span>)        │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ batch_normalizatio… │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">78</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>)    │        <span style=\"color: #00af00; text-decoration-color: #00af00\">256</span> │ conv1d_11[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]   │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">BatchNormalizatio…</span> │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ add_5 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Add</span>)         │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">78</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>)    │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ activation_5[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">…</span> │\n",
       "│                     │                   │            │ batch_normalizat… │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ max_pooling1d_5     │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">19</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>)    │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ add_5[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]       │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">MaxPooling1D</span>)      │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ flatten (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Flatten</span>)   │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">1216</span>)      │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ max_pooling1d_5[<span style=\"color: #00af00; text-decoration-color: #00af00\">…</span> │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ dense (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>)       │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>)        │     <span style=\"color: #00af00; text-decoration-color: #00af00\">77,888</span> │ flatten[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]     │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ dropout (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dropout</span>)   │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>)        │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ dense[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]       │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ dense_1 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>)     │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>)        │      <span style=\"color: #00af00; text-decoration-color: #00af00\">2,080</span> │ dropout[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]     │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ dropout_1 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dropout</span>) │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>)        │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ dense_1[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]     │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ input_layer_1       │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">10</span>)        │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ -                 │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">InputLayer</span>)        │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ concatenate         │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">42</span>)        │          <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │ dropout_1[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>],  │\n",
       "│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Concatenate</span>)       │                   │            │ input_layer_1[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>]… │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ dense_2 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>)     │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">1</span>)         │         <span style=\"color: #00af00; text-decoration-color: #00af00\">43</span> │ concatenate[<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>][<span style=\"color: #00af00; text-decoration-color: #00af00\">0</span>] │\n",
       "└─────────────────────┴───────────────────┴────────────┴───────────────────┘\n",
       "</pre>\n"
      ],
      "text/plain": [
       "┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓\n",
       "┃\u001b[1m \u001b[0m\u001b[1mLayer (type)       \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape     \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m   Param #\u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mConnected to     \u001b[0m\u001b[1m \u001b[0m┃\n",
       "┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩\n",
       "│ input_layer         │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m5000\u001b[0m, \u001b[38;5;34m12\u001b[0m)  │          \u001b[38;5;34m0\u001b[0m │ -                 │\n",
       "│ (\u001b[38;5;33mInputLayer\u001b[0m)        │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d (\u001b[38;5;33mConv1D\u001b[0m)     │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m5000\u001b[0m, \u001b[38;5;34m16\u001b[0m)  │        \u001b[38;5;34m976\u001b[0m │ input_layer[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m] │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ spatial_dropout1d   │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m5000\u001b[0m, \u001b[38;5;34m16\u001b[0m)  │          \u001b[38;5;34m0\u001b[0m │ conv1d[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]      │\n",
       "│ (\u001b[38;5;33mSpatialDropout1D\u001b[0m)  │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ batch_normalization │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m5000\u001b[0m, \u001b[38;5;34m16\u001b[0m)  │         \u001b[38;5;34m64\u001b[0m │ spatial_dropout1… │\n",
       "│ (\u001b[38;5;33mBatchNormalizatio…\u001b[0m │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_1 (\u001b[38;5;33mConv1D\u001b[0m)   │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m5000\u001b[0m, \u001b[38;5;34m16\u001b[0m)  │        \u001b[38;5;34m208\u001b[0m │ input_layer[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m] │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ activation          │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m5000\u001b[0m, \u001b[38;5;34m16\u001b[0m)  │          \u001b[38;5;34m0\u001b[0m │ batch_normalizat… │\n",
       "│ (\u001b[38;5;33mActivation\u001b[0m)        │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ batch_normalizatio… │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m5000\u001b[0m, \u001b[38;5;34m16\u001b[0m)  │         \u001b[38;5;34m64\u001b[0m │ conv1d_1[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]    │\n",
       "│ (\u001b[38;5;33mBatchNormalizatio…\u001b[0m │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ add (\u001b[38;5;33mAdd\u001b[0m)           │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m5000\u001b[0m, \u001b[38;5;34m16\u001b[0m)  │          \u001b[38;5;34m0\u001b[0m │ activation[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m], │\n",
       "│                     │                   │            │ batch_normalizat… │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ max_pooling1d       │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m2500\u001b[0m, \u001b[38;5;34m16\u001b[0m)  │          \u001b[38;5;34m0\u001b[0m │ add[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]         │\n",
       "│ (\u001b[38;5;33mMaxPooling1D\u001b[0m)      │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_2 (\u001b[38;5;33mConv1D\u001b[0m)   │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m2500\u001b[0m, \u001b[38;5;34m16\u001b[0m)  │      \u001b[38;5;34m1,296\u001b[0m │ max_pooling1d[\u001b[38;5;34m0\u001b[0m]… │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ spatial_dropout1d_1 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m2500\u001b[0m, \u001b[38;5;34m16\u001b[0m)  │          \u001b[38;5;34m0\u001b[0m │ conv1d_2[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]    │\n",
       "│ (\u001b[38;5;33mSpatialDropout1D\u001b[0m)  │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ batch_normalizatio… │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m2500\u001b[0m, \u001b[38;5;34m16\u001b[0m)  │         \u001b[38;5;34m64\u001b[0m │ spatial_dropout1… │\n",
       "│ (\u001b[38;5;33mBatchNormalizatio…\u001b[0m │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_3 (\u001b[38;5;33mConv1D\u001b[0m)   │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m2500\u001b[0m, \u001b[38;5;34m16\u001b[0m)  │        \u001b[38;5;34m272\u001b[0m │ max_pooling1d[\u001b[38;5;34m0\u001b[0m]… │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ activation_1        │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m2500\u001b[0m, \u001b[38;5;34m16\u001b[0m)  │          \u001b[38;5;34m0\u001b[0m │ batch_normalizat… │\n",
       "│ (\u001b[38;5;33mActivation\u001b[0m)        │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ batch_normalizatio… │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m2500\u001b[0m, \u001b[38;5;34m16\u001b[0m)  │         \u001b[38;5;34m64\u001b[0m │ conv1d_3[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]    │\n",
       "│ (\u001b[38;5;33mBatchNormalizatio…\u001b[0m │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ add_1 (\u001b[38;5;33mAdd\u001b[0m)         │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m2500\u001b[0m, \u001b[38;5;34m16\u001b[0m)  │          \u001b[38;5;34m0\u001b[0m │ activation_1[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m…\u001b[0m │\n",
       "│                     │                   │            │ batch_normalizat… │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ max_pooling1d_1     │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1250\u001b[0m, \u001b[38;5;34m16\u001b[0m)  │          \u001b[38;5;34m0\u001b[0m │ add_1[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]       │\n",
       "│ (\u001b[38;5;33mMaxPooling1D\u001b[0m)      │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_4 (\u001b[38;5;33mConv1D\u001b[0m)   │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1250\u001b[0m, \u001b[38;5;34m32\u001b[0m)  │      \u001b[38;5;34m2,592\u001b[0m │ max_pooling1d_1[\u001b[38;5;34m…\u001b[0m │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ spatial_dropout1d_2 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1250\u001b[0m, \u001b[38;5;34m32\u001b[0m)  │          \u001b[38;5;34m0\u001b[0m │ conv1d_4[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]    │\n",
       "│ (\u001b[38;5;33mSpatialDropout1D\u001b[0m)  │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ batch_normalizatio… │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1250\u001b[0m, \u001b[38;5;34m32\u001b[0m)  │        \u001b[38;5;34m128\u001b[0m │ spatial_dropout1… │\n",
       "│ (\u001b[38;5;33mBatchNormalizatio…\u001b[0m │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_5 (\u001b[38;5;33mConv1D\u001b[0m)   │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1250\u001b[0m, \u001b[38;5;34m32\u001b[0m)  │        \u001b[38;5;34m544\u001b[0m │ max_pooling1d_1[\u001b[38;5;34m…\u001b[0m │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ activation_2        │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1250\u001b[0m, \u001b[38;5;34m32\u001b[0m)  │          \u001b[38;5;34m0\u001b[0m │ batch_normalizat… │\n",
       "│ (\u001b[38;5;33mActivation\u001b[0m)        │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ batch_normalizatio… │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1250\u001b[0m, \u001b[38;5;34m32\u001b[0m)  │        \u001b[38;5;34m128\u001b[0m │ conv1d_5[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]    │\n",
       "│ (\u001b[38;5;33mBatchNormalizatio…\u001b[0m │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ add_2 (\u001b[38;5;33mAdd\u001b[0m)         │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1250\u001b[0m, \u001b[38;5;34m32\u001b[0m)  │          \u001b[38;5;34m0\u001b[0m │ activation_2[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m…\u001b[0m │\n",
       "│                     │                   │            │ batch_normalizat… │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ max_pooling1d_2     │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m312\u001b[0m, \u001b[38;5;34m32\u001b[0m)   │          \u001b[38;5;34m0\u001b[0m │ add_2[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]       │\n",
       "│ (\u001b[38;5;33mMaxPooling1D\u001b[0m)      │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_6 (\u001b[38;5;33mConv1D\u001b[0m)   │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m312\u001b[0m, \u001b[38;5;34m32\u001b[0m)   │      \u001b[38;5;34m3,104\u001b[0m │ max_pooling1d_2[\u001b[38;5;34m…\u001b[0m │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ spatial_dropout1d_3 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m312\u001b[0m, \u001b[38;5;34m32\u001b[0m)   │          \u001b[38;5;34m0\u001b[0m │ conv1d_6[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]    │\n",
       "│ (\u001b[38;5;33mSpatialDropout1D\u001b[0m)  │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ batch_normalizatio… │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m312\u001b[0m, \u001b[38;5;34m32\u001b[0m)   │        \u001b[38;5;34m128\u001b[0m │ spatial_dropout1… │\n",
       "│ (\u001b[38;5;33mBatchNormalizatio…\u001b[0m │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_7 (\u001b[38;5;33mConv1D\u001b[0m)   │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m312\u001b[0m, \u001b[38;5;34m32\u001b[0m)   │      \u001b[38;5;34m1,056\u001b[0m │ max_pooling1d_2[\u001b[38;5;34m…\u001b[0m │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ activation_3        │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m312\u001b[0m, \u001b[38;5;34m32\u001b[0m)   │          \u001b[38;5;34m0\u001b[0m │ batch_normalizat… │\n",
       "│ (\u001b[38;5;33mActivation\u001b[0m)        │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ batch_normalizatio… │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m312\u001b[0m, \u001b[38;5;34m32\u001b[0m)   │        \u001b[38;5;34m128\u001b[0m │ conv1d_7[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]    │\n",
       "│ (\u001b[38;5;33mBatchNormalizatio…\u001b[0m │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ add_3 (\u001b[38;5;33mAdd\u001b[0m)         │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m312\u001b[0m, \u001b[38;5;34m32\u001b[0m)   │          \u001b[38;5;34m0\u001b[0m │ activation_3[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m…\u001b[0m │\n",
       "│                     │                   │            │ batch_normalizat… │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ max_pooling1d_3     │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m156\u001b[0m, \u001b[38;5;34m32\u001b[0m)   │          \u001b[38;5;34m0\u001b[0m │ add_3[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]       │\n",
       "│ (\u001b[38;5;33mMaxPooling1D\u001b[0m)      │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_8 (\u001b[38;5;33mConv1D\u001b[0m)   │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m156\u001b[0m, \u001b[38;5;34m64\u001b[0m)   │      \u001b[38;5;34m6,208\u001b[0m │ max_pooling1d_3[\u001b[38;5;34m…\u001b[0m │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ spatial_dropout1d_4 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m156\u001b[0m, \u001b[38;5;34m64\u001b[0m)   │          \u001b[38;5;34m0\u001b[0m │ conv1d_8[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]    │\n",
       "│ (\u001b[38;5;33mSpatialDropout1D\u001b[0m)  │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ batch_normalizatio… │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m156\u001b[0m, \u001b[38;5;34m64\u001b[0m)   │        \u001b[38;5;34m256\u001b[0m │ spatial_dropout1… │\n",
       "│ (\u001b[38;5;33mBatchNormalizatio…\u001b[0m │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_9 (\u001b[38;5;33mConv1D\u001b[0m)   │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m156\u001b[0m, \u001b[38;5;34m64\u001b[0m)   │      \u001b[38;5;34m2,112\u001b[0m │ max_pooling1d_3[\u001b[38;5;34m…\u001b[0m │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ activation_4        │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m156\u001b[0m, \u001b[38;5;34m64\u001b[0m)   │          \u001b[38;5;34m0\u001b[0m │ batch_normalizat… │\n",
       "│ (\u001b[38;5;33mActivation\u001b[0m)        │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ batch_normalizatio… │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m156\u001b[0m, \u001b[38;5;34m64\u001b[0m)   │        \u001b[38;5;34m256\u001b[0m │ conv1d_9[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]    │\n",
       "│ (\u001b[38;5;33mBatchNormalizatio…\u001b[0m │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ add_4 (\u001b[38;5;33mAdd\u001b[0m)         │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m156\u001b[0m, \u001b[38;5;34m64\u001b[0m)   │          \u001b[38;5;34m0\u001b[0m │ activation_4[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m…\u001b[0m │\n",
       "│                     │                   │            │ batch_normalizat… │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ max_pooling1d_4     │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m78\u001b[0m, \u001b[38;5;34m64\u001b[0m)    │          \u001b[38;5;34m0\u001b[0m │ add_4[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]       │\n",
       "│ (\u001b[38;5;33mMaxPooling1D\u001b[0m)      │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_10 (\u001b[38;5;33mConv1D\u001b[0m)  │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m78\u001b[0m, \u001b[38;5;34m64\u001b[0m)    │     \u001b[38;5;34m12,352\u001b[0m │ max_pooling1d_4[\u001b[38;5;34m…\u001b[0m │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ spatial_dropout1d_5 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m78\u001b[0m, \u001b[38;5;34m64\u001b[0m)    │          \u001b[38;5;34m0\u001b[0m │ conv1d_10[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]   │\n",
       "│ (\u001b[38;5;33mSpatialDropout1D\u001b[0m)  │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ batch_normalizatio… │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m78\u001b[0m, \u001b[38;5;34m64\u001b[0m)    │        \u001b[38;5;34m256\u001b[0m │ spatial_dropout1… │\n",
       "│ (\u001b[38;5;33mBatchNormalizatio…\u001b[0m │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ conv1d_11 (\u001b[38;5;33mConv1D\u001b[0m)  │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m78\u001b[0m, \u001b[38;5;34m64\u001b[0m)    │      \u001b[38;5;34m4,160\u001b[0m │ max_pooling1d_4[\u001b[38;5;34m…\u001b[0m │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ activation_5        │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m78\u001b[0m, \u001b[38;5;34m64\u001b[0m)    │          \u001b[38;5;34m0\u001b[0m │ batch_normalizat… │\n",
       "│ (\u001b[38;5;33mActivation\u001b[0m)        │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ batch_normalizatio… │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m78\u001b[0m, \u001b[38;5;34m64\u001b[0m)    │        \u001b[38;5;34m256\u001b[0m │ conv1d_11[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]   │\n",
       "│ (\u001b[38;5;33mBatchNormalizatio…\u001b[0m │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ add_5 (\u001b[38;5;33mAdd\u001b[0m)         │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m78\u001b[0m, \u001b[38;5;34m64\u001b[0m)    │          \u001b[38;5;34m0\u001b[0m │ activation_5[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m…\u001b[0m │\n",
       "│                     │                   │            │ batch_normalizat… │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ max_pooling1d_5     │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m19\u001b[0m, \u001b[38;5;34m64\u001b[0m)    │          \u001b[38;5;34m0\u001b[0m │ add_5[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]       │\n",
       "│ (\u001b[38;5;33mMaxPooling1D\u001b[0m)      │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ flatten (\u001b[38;5;33mFlatten\u001b[0m)   │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1216\u001b[0m)      │          \u001b[38;5;34m0\u001b[0m │ max_pooling1d_5[\u001b[38;5;34m…\u001b[0m │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ dense (\u001b[38;5;33mDense\u001b[0m)       │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m64\u001b[0m)        │     \u001b[38;5;34m77,888\u001b[0m │ flatten[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]     │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ dropout (\u001b[38;5;33mDropout\u001b[0m)   │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m64\u001b[0m)        │          \u001b[38;5;34m0\u001b[0m │ dense[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]       │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ dense_1 (\u001b[38;5;33mDense\u001b[0m)     │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m32\u001b[0m)        │      \u001b[38;5;34m2,080\u001b[0m │ dropout[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]     │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ dropout_1 (\u001b[38;5;33mDropout\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m32\u001b[0m)        │          \u001b[38;5;34m0\u001b[0m │ dense_1[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m]     │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ input_layer_1       │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m10\u001b[0m)        │          \u001b[38;5;34m0\u001b[0m │ -                 │\n",
       "│ (\u001b[38;5;33mInputLayer\u001b[0m)        │                   │            │                   │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ concatenate         │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m42\u001b[0m)        │          \u001b[38;5;34m0\u001b[0m │ dropout_1[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m],  │\n",
       "│ (\u001b[38;5;33mConcatenate\u001b[0m)       │                   │            │ input_layer_1[\u001b[38;5;34m0\u001b[0m]… │\n",
       "├─────────────────────┼───────────────────┼────────────┼───────────────────┤\n",
       "│ dense_2 (\u001b[38;5;33mDense\u001b[0m)     │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1\u001b[0m)         │         \u001b[38;5;34m43\u001b[0m │ concatenate[\u001b[38;5;34m0\u001b[0m][\u001b[38;5;34m0\u001b[0m] │\n",
       "└─────────────────────┴───────────────────┴────────────┴───────────────────┘\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Total params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">116,683</span> (455.79 KB)\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1m Total params: \u001b[0m\u001b[38;5;34m116,683\u001b[0m (455.79 KB)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">115,787</span> (452.29 KB)\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m115,787\u001b[0m (452.29 KB)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Non-trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">896</span> (3.50 KB)\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m896\u001b[0m (3.50 KB)\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "None\n",
      "Epoch 1/20\n",
      "\u001b[1m200/200\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m821s\u001b[0m 4s/step - accuracy: 0.8502 - auc: 0.5239 - auprc: 0.1217 - loss: 0.4734 - val_accuracy: 0.8792 - val_auc: 0.5955 - val_auprc: 0.1474 - val_loss: 0.3741 - learning_rate: 0.0010\n",
      "Epoch 2/20\n",
      "\u001b[1m200/200\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m624s\u001b[0m 3s/step - accuracy: 0.8857 - auc: 0.5693 - auprc: 0.1493 - loss: 0.3777 - val_accuracy: 0.8831 - val_auc: 0.6514 - val_auprc: 0.1710 - val_loss: 0.3489 - learning_rate: 0.0010\n",
      "Epoch 3/20\n",
      "\u001b[1m200/200\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m620s\u001b[0m 3s/step - accuracy: 0.8813 - auc: 0.5946 - auprc: 0.1496 - loss: 0.3613 - val_accuracy: 0.8837 - val_auc: 0.6873 - val_auprc: 0.1956 - val_loss: 0.3391 - learning_rate: 0.0010\n",
      "Epoch 4/20\n",
      "\u001b[1m200/200\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m620s\u001b[0m 3s/step - accuracy: 0.8853 - auc: 0.6235 - auprc: 0.1652 - loss: 0.3532 - val_accuracy: 0.8836 - val_auc: 0.7098 - val_auprc: 0.2190 - val_loss: 0.3361 - learning_rate: 0.0010\n",
      "Epoch 5/20\n",
      "\u001b[1m200/200\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m626s\u001b[0m 3s/step - accuracy: 0.8850 - auc: 0.6523 - auprc: 0.2104 - loss: 0.3466 - val_accuracy: 0.8840 - val_auc: 0.7266 - val_auprc: 0.2410 - val_loss: 0.3411 - learning_rate: 0.0010\n",
      "Epoch 6/20\n",
      "\u001b[1m200/200\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m639s\u001b[0m 3s/step - accuracy: 0.8820 - auc: 0.6942 - auprc: 0.2303 - loss: 0.3366 - val_accuracy: 0.8844 - val_auc: 0.7316 - val_auprc: 0.2491 - val_loss: 0.3334 - learning_rate: 0.0010\n",
      "Epoch 7/20\n",
      "\u001b[1m200/200\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m653s\u001b[0m 3s/step - accuracy: 0.8846 - auc: 0.6856 - auprc: 0.2182 - loss: 0.3371 - val_accuracy: 0.8844 - val_auc: 0.7215 - val_auprc: 0.2370 - val_loss: 0.3275 - learning_rate: 0.0010\n",
      "Epoch 8/20\n",
      "\u001b[1m200/200\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m555s\u001b[0m 3s/step - accuracy: 0.8857 - auc: 0.6790 - auprc: 0.2254 - loss: 0.3377 - val_accuracy: 0.8842 - val_auc: 0.7403 - val_auprc: 0.2567 - val_loss: 0.3304 - learning_rate: 0.0010\n",
      "Epoch 9/20\n",
      "\u001b[1m200/200\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m555s\u001b[0m 3s/step - accuracy: 0.8805 - auc: 0.7053 - auprc: 0.2396 - loss: 0.3364 - val_accuracy: 0.8837 - val_auc: 0.7382 - val_auprc: 0.2493 - val_loss: 0.3316 - learning_rate: 0.0010\n",
      "Epoch 10/20\n",
      "\u001b[1m200/200\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m545s\u001b[0m 3s/step - accuracy: 0.8842 - auc: 0.7036 - auprc: 0.2458 - loss: 0.3331 - val_accuracy: 0.8834 - val_auc: 0.7387 - val_auprc: 0.2521 - val_loss: 0.3290 - learning_rate: 0.0010\n",
      "Epoch 11/20\n",
      "\u001b[1m200/200\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m563s\u001b[0m 3s/step - accuracy: 0.8837 - auc: 0.7250 - auprc: 0.2554 - loss: 0.3252 - val_accuracy: 0.8787 - val_auc: 0.7379 - val_auprc: 0.2543 - val_loss: 0.3445 - learning_rate: 0.0010\n",
      "Epoch 12/20\n",
      "\u001b[1m200/200\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m564s\u001b[0m 3s/step - accuracy: 0.8833 - auc: 0.7125 - auprc: 0.2401 - loss: 0.3309 - val_accuracy: 0.8814 - val_auc: 0.7392 - val_auprc: 0.2538 - val_loss: 0.3426 - learning_rate: 0.0010\n",
      "Epoch 13/20\n",
      "\u001b[1m200/200\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m561s\u001b[0m 3s/step - accuracy: 0.8871 - auc: 0.7235 - auprc: 0.2629 - loss: 0.3193 - val_accuracy: 0.8817 - val_auc: 0.7378 - val_auprc: 0.2538 - val_loss: 0.3306 - learning_rate: 0.0010\n",
      "Epoch 14/20\n",
      "\u001b[1m200/200\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m566s\u001b[0m 3s/step - accuracy: 0.8853 - auc: 0.7315 - auprc: 0.2569 - loss: 0.3190 - val_accuracy: 0.8803 - val_auc: 0.7390 - val_auprc: 0.2568 - val_loss: 0.3411 - learning_rate: 0.0010\n",
      "Epoch 15/20\n",
      "\u001b[1m200/200\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m551s\u001b[0m 3s/step - accuracy: 0.8823 - auc: 0.7319 - auprc: 0.2623 - loss: 0.3231 - val_accuracy: 0.8823 - val_auc: 0.7340 - val_auprc: 0.2528 - val_loss: 0.3307 - learning_rate: 0.0010\n",
      "Epoch 16/20\n",
      "\u001b[1m200/200\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m552s\u001b[0m 3s/step - accuracy: 0.8835 - auc: 0.7431 - auprc: 0.2710 - loss: 0.3187 - val_accuracy: 0.8830 - val_auc: 0.7301 - val_auprc: 0.2475 - val_loss: 0.3298 - learning_rate: 0.0010\n",
      "Epoch 17/20\n",
      "\u001b[1m200/200\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m553s\u001b[0m 3s/step - accuracy: 0.8849 - auc: 0.7617 - auprc: 0.2951 - loss: 0.3082 - val_accuracy: 0.8804 - val_auc: 0.7304 - val_auprc: 0.2475 - val_loss: 0.3327 - learning_rate: 0.0010\n"
     ]
    }
   ],
   "source": [
    "\n",
    "# Define and build the model\n",
    "fusion_model = Attia_et_al_fusion()\n",
    "model = fusion_model.build(input_shape=(5000, 12), fusion_shape=(train_tab_data.shape[1],))\n",
    "\n",
    "# Compile the model\n",
    "model.compile(\n",
    "    optimizer='adam', \n",
    "    loss='binary_crossentropy', \n",
    "    metrics=['accuracy', AUC(name='auc'), AUC(name='auprc', curve='PR')]\n",
    ")\n",
    "\n",
    "# Training parameters\n",
    "EPOCHS = 20\n",
    "\n",
    "# Callbacks (example)\n",
    "reduce_lr = tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=5, min_lr=0.001)\n",
    "early_stopping = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=10, restore_best_weights=True)\n",
    "\n",
    "# Train the model\n",
    "history = model.fit(\n",
    "    train_dataset,\n",
    "    validation_data=val_dataset,\n",
    "    epochs=EPOCHS,\n",
    "    steps_per_epoch=steps_per_epoch,\n",
    "    validation_steps=validation_steps,\n",
    "    callbacks=[reduce_lr, early_stopping],\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "a0a2bd02-2f8c-478e-b210-8754bec0dc47",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Save the trained model\n",
    "model.save('trained_fusion_model_hfpefvsall.keras')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "c64526b0-ff04-4879-884e-d4b08bb8f0b8",
   "metadata": {},
   "outputs": [],
   "source": [
    "trained_model = tf.keras.models.load_model('trained_fusion_model_hfpef_hfref.keras', custom_objects={'AUC': tf.keras.metrics.AUC})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "5012e024-1de2-44d5-887d-6544929916f7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[1m171/171\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m357s\u001b[0m 2s/step - accuracy: 0.3645 - auc: 0.5432 - auprc: 0.1378 - loss: 0.8228\n",
      "Test Loss: 0.8224946856498718\n",
      "Test Accuracy: 0.3662280738353729\n",
      "Test AUC: 0.550576388835907\n",
      "Test AUPRC: 0.13828331232070923\n"
     ]
    }
   ],
   "source": [
    "# Evaluate the model on the test dataset\n",
    "test_loss, test_accuracy, test_auc, test_auprc = trained_model.evaluate(test_dataset, steps=test_steps)\n",
    "\n",
    "# Print the evaluation results\n",
    "print(f\"Test Loss: {test_loss}\")\n",
    "print(f\"Test Accuracy: {test_accuracy}\")\n",
    "print(f\"Test AUC: {test_auc}\")\n",
    "print(f\"Test AUPRC: {test_auprc}\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.17"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
